/**
 * 
 */
package com.gd.deron.smartrobot.baobao.service;

import java.io.UnsupportedEncodingException;
import java.nio.Buffer;
import java.util.HashMap;
import java.util.Iterator;

import com.gd.deron.smartrobot.baobao.app.MyApplication;
import com.gd.deron.smartrobot.baobao.info.MusicNameInfo;
import com.gd.deron.smartrobot.baobao.info.OrderInfo;
import com.gd.deron.smartrobot.baobao.utils.BlueTools;
import com.gd.deron.smartrobot.baobao.utils.Config;
import com.gd.deron.smartrobot.baobao.utils.InstructionUtil;
import com.gd.deron.smartrobot.baobao.utils.PlayMusicTool;
import com.gd.deron.smartrobot.baobao.utils.UsbHostUtils;

import android.R.bool;
import android.app.PendingIntent;
import android.app.Service;
import android.content.BroadcastReceiver;
import android.content.Context;
import android.content.Intent;
import android.content.IntentFilter;
import android.hardware.usb.UsbDevice;
import android.hardware.usb.UsbManager;
import android.os.Binder;
import android.os.IBinder;
import android.os.Message;
import android.os.UserHandle;
import android.util.Log;
import android.widget.Toast;
import cn.wch.ch34xuartdriver.CH34xUARTDriver;

/**
 * @author caiqingming 20170522
 *
 */
public class SerialPostService extends Service {
	
	public static final String TAG = "SerialPostService";
	private static final String ACTION_USB_PERMISSION = "cn.wch.wchusbdriver.USB_PERMISSION";

	protected final Object ThreadLock = new Object();
	public boolean isOpen;
	private int retval;
	private int baudRate = 9600;
	private byte stopBit = 1;
	private byte dataBit = 8;
	private byte parity = 0;
	private byte flowControl = 0;
	private UsbManager manager;
	private SerialPostBinder mBinder = new SerialPostBinder();
	private UsbDevice device = null;
	private int myvid = 1155, mypid = 22336;
	@Override
	public void onCreate() {
		super.onCreate();
		init();
	}
	
	private void init() {
		MyApplication.driver = new CH34xUARTDriver((UsbManager) getSystemService(Context.USB_SERVICE), this,
				ACTION_USB_PERMISSION);
		if (!MyApplication.driver.UsbFeatureSupported())// 判断系统是否支持USB HOST
			Toast.makeText(this, "您的手机不支持USB HOST，请更换其他手机再试！", 0).show();
		isOpen = false;
		
		manager = (UsbManager) getSystemService(Context.USB_SERVICE);
		HashMap<String, UsbDevice> deviceList = manager.getDeviceList();
		Iterator<UsbDevice> deviceIterator = deviceList.values().iterator();
		while (deviceIterator.hasNext()) {
			device = deviceIterator.next();
			Log.i(TAG, "vid: " + device.getVendorId() + "\t pid: " + device.getProductId());
			if (device.getVendorId() == myvid && device.getProductId() == mypid) {
				//broadcastSend(Config.DEVICE_DATA,"VendorId="+device.getVendorId()+"ProductId="+device.getProductId());
				break;
			}
		}
		if (device != null && device.getVendorId() == myvid && device.getProductId() == mypid) {
			//broadcastSend(Config.FIND_DEVICE);
		} 
		PendingIntent  mPermissionIntent = PendingIntent.getBroadcast(this, 0, new Intent(ACTION_USB_PERMISSION), 0);
		try {
			if (!manager.hasPermission(device)) {
				Toast.makeText(this, "请求权限", 0).show();
				manager.requestPermission(device, mPermissionIntent);
			}else{
				openDevice();
			}
		} catch (Exception e) {
		//	broadcastSend(Config.DEVICE_DATA,"Permission Exception ="+e.getMessage());
			Toast.makeText(this, "Permission Exception ="+e.toString(), Toast.LENGTH_SHORT).show();
		}
		IntentFilter filter = new IntentFilter(ACTION_USB_PERMISSION);
		registerReceiver(mUsbReceiver, filter); 
		
	}
	
	
	private final BroadcastReceiver mUsbReceiver = new BroadcastReceiver() {  
	    public void onReceive(Context context, Intent intent) {  
	    	
	        String action = intent.getAction();  
	    if (ACTION_USB_PERMISSION.equals(action)){  
				synchronized (this) {
					UsbDevice device = (UsbDevice) intent.getParcelableExtra(UsbManager.EXTRA_DEVICE);
					if (intent.getBooleanExtra(UsbManager.EXTRA_PERMISSION_GRANTED, false)) {
						if (device != null) {
							Toast.makeText(SerialPostService.this, "同意", 0).show();// 用户同意之后打开设备
							openDevice();
						}
					} else {
						Toast.makeText(SerialPostService.this, "取消", 0).show();
					}
				}
			}
	    }  
	};
	@Override
	public int onStartCommand(Intent intent, int flags, int startId) {
		return super.onStartCommand(intent, flags, startId);
		
	}
	private void setSerialPostConfig() {
		// 设置 UART 接口的波特率、数据位、停止位、奇偶校验位以及流控
		if (MyApplication.driver.SetConfig(baudRate, dataBit, stopBit, parity, // 配置串口波特率，函数说明可参照编程手册
				flowControl)) {
			//Toast.makeText(this, "串口设置成功!", Toast.LENGTH_SHORT).show();
		} else {
			Toast.makeText(this, "串口设置失败!", Toast.LENGTH_SHORT).show();
		}
	}
	
	
	public void sendToData(String data){
		if(!isOpen){
			openDevice();
			return;
		}
		//byte[] to_send = UsbHostUtils.stringToByteArray(data);
		byte[] to_send = null;
		try {
			to_send = data.getBytes("gb2312");
		} catch (UnsupportedEncodingException e) {
			e.printStackTrace();
		}
		int retval = MyApplication.driver.WriteData(to_send, to_send.length);// 写数据，第一个参数为需要发送的字节数组，第二个参数为需要发送的字节长度，返回实际发送的字节长度
		//Toast.makeText(this,"发送数据"+ data, Toast.LENGTH_SHORT).show();
		if (retval < 0)
			Toast.makeText(this, "写失败!", Toast.LENGTH_SHORT).show();
	}
	public void openDevice() {
		if (!MyApplication.driver.isConnected()) {
			retval = MyApplication.driver.ResumeUsbList();
			if (retval == -1)// ResumeUsbList方法用于枚举CH34X设备以及打开相关设备
			{
				Toast.makeText(this, "打开设备失败!", Toast.LENGTH_SHORT).show();
				MyApplication.driver.CloseDevice();
				MyApplication.isConnect = false;//标识为true
				broadcastSend(Config.DISCONNECTED);
			} else if (retval == 0) {
				if (!MyApplication.driver.UartInit()) {// 对串口设备进行初始化操作
					Toast.makeText(this, "设备初始化失败!", Toast.LENGTH_SHORT).show();
					return;
				}
				//Toast.makeText(this, "打开设备成功!", Toast.LENGTH_SHORT).show();
				isOpen = true;
				MyApplication.isConnect = true;//标识为true
				broadcastSend(Config.CON_SUCCESS);
				setSerialPostConfig();
				new readThread().start();// 开启读线程读取串口接收的数据
			} 
		} else {
			closeDevice();
		}
		
	}
	public void closeDevice(){
		MyApplication.driver.CloseDevice();
		isOpen = false;
	}
	private class readThread extends Thread {

		public void run() {

			byte[] buffer = new byte[1024];

			while (true) {
				//Message msg = Message.obtain();
				if (!MyApplication.driver.isConnected()) {
					broadcastSend(Config.DISCONNECTED);
					break;
				}
				int length = MyApplication.driver.ReadData(buffer, 16);
				if (length > 0) {
					String recv = UsbHostUtils.byteToHexString(buffer, length);
					
					if(recv.startsWith("AA")&&recv.endsWith("AA")){
						broadcastSend(Config.RECEIVE_DATA,recv);
						receiverData(recv);
					}else{
					
						String ss = null;
						try {
							ss = new String(buffer,0,length,"GB2312");
						} catch (UnsupportedEncodingException e) {
							e.printStackTrace();
						}
						MyApplication.ANSWERANDQUESTION = ss;
						Log.e(TAG, ">>>>>>>>>>>>"+ss);
						broadcastSend(Config.SUBMIT_QUESTION_ANSWER);
						broadcastSend(Config.RECEIVE_DATA,ss);
					}
					
				}
			}
		}
	}

	private void receiverData(String codeString){
		if(codeString.startsWith("AABBCC")){
			switch (codeString) {
			case OrderInfo.STASR_ASR://收到开始语音指令。开始对话
				broadcastSend(Config.START_ASR);
				break;
			case OrderInfo.STASR_ASR_UP://松开手
				broadcastSend(Config.STOP_ASR);
				break;
			case OrderInfo.STASR_ASR_COPY://收到开始语音指令。开始对话
				broadcastSend(Config.START_ASR_COPY);
				break;
			case OrderInfo.STASR_ASR_UP_COPY://松开手
				broadcastSend(Config.STOP_ASR_COPY);
				break;
			case OrderInfo.VOICE://松开手
				broadcastSend(Config.VOICE);
				break;
			case OrderInfo.TOUCH_DOWN://触摸按下
				broadcastSend(Config.TOUCH_DOWN);
				break;
			case OrderInfo.TOUCH_UP://触摸松开
				broadcastSend(Config.TOUCH_UP);
				break;
			default:
				break;
			}
		}else if(codeString.startsWith("AABBEE")){
			if(codeString.equals(MusicNameInfo.MUSIC_STOP)){
				PlayMusicTool.close();
			}else{
				try {
					int data = Integer.parseInt(codeString.substring(8, 10 ), 16)-1;
					PlayMusicTool.getInstance().playMusicToTitle(MusicNameInfo.MUSIC_ARR[data], getApplicationContext(), "song");
					Log.e(TAG, MusicNameInfo.MUSIC_ARR[data]);
				} catch (Exception e) {
				}
			}
			
		}else if(codeString.startsWith("AABBFF")){//语音合成
			
			try {
				int data = Integer.parseInt(codeString.substring(8, 10 ), 16);
				MyApplication.ASR = MusicNameInfo.PLAY_TTS_ARR[data];
				Log.e(TAG, MusicNameInfo.PLAY_TTS_ARR[data]);
				broadcastSend(Config.ASR_ANSWER );
			} catch (Exception e) {
			}
			
		}else if(codeString.equals(InstructionUtil.CLEAR_DATA)){//清除本地语音录入数据库
			broadcastSend(Config.CLEAR_ARS_SQL);
		}else if(codeString.equals(InstructionUtil.WAKE_ROBOT_OFFLINE)){//一键唤醒离线
			broadcastSend(Config.WAKE_ROBOT_OFFLINE);
		}else if(codeString.equals(InstructionUtil.WAKE_ROBOT_ONLINE)){//一键唤醒在线
			broadcastSend(Config.WAKE_ROBOT_ONLINE);
		}else{
			
		}
	}
	/** 发送广播 */
	private void broadcastSend(final String action) {
		final Intent inte = new Intent(action);
		sendBroadcast(inte);
	}

	/** 发送带数据的广播 */
	private void broadcastSend(final String action, String order) {
		final Intent inte = new Intent(action);
		inte.putExtra("data", order);
		sendBroadcast(inte);
	}
	@Override
	public IBinder onBind(Intent intent) {
		return mBinder;
	}
	
	public class SerialPostBinder extends Binder{
		public SerialPostService getSerialPostService(){
			return SerialPostService.this;
		}
	}

}
